package com.niiwoo.civet.user.service.duboo;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.snapdata.dto.request.EducationSaveReqDTO;
import com.niiwoo.civet.snapdata.service.EducationDubboService;
import com.niiwoo.civet.user.dto.UserPersonalDubboInfoDTO;
import com.niiwoo.civet.user.dto.response.ThirdAuthResponseDTO;
import com.niiwoo.civet.user.dto.response.UserRealNameInfoDTO;
import com.niiwoo.civet.user.enums.EducationMatchEnum;
import com.niiwoo.civet.user.enums.UserDataTypeEnum;
import com.niiwoo.civet.user.enums.UserPersonalEnum;
import com.niiwoo.civet.user.service.UserAuthEducationDubboService;
import com.niiwoo.civet.user.service.UserDataDubboService;
import com.niiwoo.civet.user.service.local.UserAuthCommonTemplateService;
import com.niiwoo.civet.user.service.local.UserDataService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.tiancheng.component.TianchengAuthEducationService;
import com.niiwoo.tripod.tiancheng.component.TianchengAuthService;
import com.niiwoo.tripod.tiancheng.enums.FunctionCodeEnum;
import com.niiwoo.tripod.tiancheng.request.auth.EducationDataQueryRequest;
import com.niiwoo.tripod.tiancheng.response.auth.EducationDataQueryResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @author zzl
 * @create 2018-04-17 15:07
 * @desc 学历授权dubbo服务类
 **/
@Slf4j
@Service(version = "1.0.0")
public class UserAuthEducationDubboServiceImpl extends UserAuthCommonTemplateService implements UserAuthEducationDubboService {

    @Autowired
    TianchengAuthEducationService tianchengAuthEducationService;

    @Autowired
    private UserDataService userDataService;

    @Autowired
    PrivacyMasks privacyMasks;

    @Reference(version = "1.0.0")
    private EducationDubboService educationDubboService;
    @Reference(version = "1.0.0")
    private UserDataDubboService userDataDubboService;

    /**
     * 上次授权失败原因显示结果页面
     */
    private final String h5ErrorMsgUrl = "{0}/html5/project/creditresult/index.html#/authorizeFail_education?t={1}&msg={2}";

    /**
     * 天秤授权同步get回调h5页面地址
     */
    private final String h5CallbackResultUrl = "/html5/project/creditresult/index.html#/index_education";

    /**
     * 天秤授权数据回调url
     */
    private final String dataCallbackUrl="/tc/authEducationData/callback";



    @Override
    public boolean authCallback(String resultJson) {
        return super.authCallback(resultJson);
    }

    @Override
    public boolean dataCallBack(String resultJson) {

        return super.dataCallBack(resultJson);

    }

    @Override
    public boolean refreshData(String userId) {
            return queryAndSaveData(userId);
    }

    private boolean queryAndSaveData(String userId){
        UserRealNameInfoDTO userRealNameInfoDTO = userDataService.getUserRealNameInfo(userId);
        if (userRealNameInfoDTO == null) {
            log.info("调用天秤h5查询用户实名信息为空,userId:" + userId);
            throw new BizException("USR19076");
        }
        if (StringUtils.isBlank(userRealNameInfoDTO.getRealName())
                || StringUtils.isBlank(userRealNameInfoDTO.getIdCard())) {
            log.info("调用天秤h5查询用户真实姓名或身份证号为空,userId:" + userId);
            throw new BizException("USR19076");
        }
        EducationDataQueryRequest request = new EducationDataQueryRequest();
        request.setRealname(userRealNameInfoDTO.getRealName());
        request.setIdcard(privacyMasks.decryptPrivacy(userRealNameInfoDTO.getIdCard()));
//        request.setRealname("郑举");
//        request.setIdcard("35032219850201309x");
        request.setFunctionCode(FunctionCodeEnum.QUERY_EDUCATION_DATA.getBodyFunctionCode());
        CompletableFuture<EducationDataQueryResponse> educationDataQueryResponseCompletableFuture = tianchengAuthEducationService.dataQuery(request);

        try {

            EducationDataQueryResponse response = educationDataQueryResponseCompletableFuture.get();

            log.info("userId={},学历信息查询天秤返回结果：{}", userId, JSON.toJSONString(response));
            String result = StringUtils.replace(response.getResult(),"\\","");
            response.setResult(result);
            if (response == null) {
                throw new BizException("USR19106");
            }

            if (StringUtils.isBlank(response.getResult())) {
                throw new BizException("USR19106");
            }
            JSONObject jsonObject = null;
            try {
                jsonObject = JSONObject.parseObject(response.getResult());
            }catch (Exception e){
                log.info(userId + "学历信息解析失败:"+response.getResult(), e);
                throw new BizException("USR19108");
            }
            JSONArray data = jsonObject.getJSONArray("data");
            List<EducationSaveReqDTO> list = new ArrayList<>(4);

            if(data == null || data.size() == 0){
                log.info(userId + "查询学历数据天秤返回空");
                throw new BizException("USR19106");
            }

            EducationSaveReqDTO lastEducationSaveReqDTO = new EducationSaveReqDTO();
            Long lastGraduateDate = 0L;
            for (int i = 0; i < data.size(); i++) {
                JSONObject edu = data.getJSONObject(i);
                EducationSaveReqDTO reqDTO = new EducationSaveReqDTO();
                reqDTO.setUserId(userId);
                reqDTO.setEnrolDate(coverToDate(edu.getLong("entranceDate")));
                reqDTO.setStudyType(edu.getString("eduForm"));
                reqDTO.setSchoolName(edu.getString("eduSchool"));
                reqDTO.setRealName(edu.getString("realName"));
                reqDTO.setEducationType(edu.getString("eduRecord"));
                Long graduateDate = edu.getLong("graduateDate");
                reqDTO.setEndDate(coverToDate(graduateDate));
                list.add(reqDTO);

                if(graduateDate > lastGraduateDate) {
                    lastGraduateDate = graduateDate;
                    lastEducationSaveReqDTO = reqDTO;
                }
            }

            log.debug("测试："+ JSON.toJSONString(list));
            Integer saveResult = educationDubboService.saveEducation(list);
            log.info("保存用户学历信息到快照数据库返回结果userId={}, result={}", userId, saveResult);

            try {
                UserPersonalDubboInfoDTO personalDubboInfoDTO = new UserPersonalDubboInfoDTO();
                personalDubboInfoDTO.setUserId(userId);
                personalDubboInfoDTO.setEducationLevel(EducationMatchEnum.enumOf(lastEducationSaveReqDTO.getEducationType()).getUserEduLevelEnum().getType());
                personalDubboInfoDTO.setEducationAuthStatus(UserPersonalEnum.EducationAuthStatusEnum.AUTH.getStatus());
                personalDubboInfoDTO.setEducationAuthTime(new Date());
                log.info("查询学历信息，同步更新个人信息表，开始：lastEducationSaveReqDTO={}"+ JSON.toJSONString(lastEducationSaveReqDTO));
                CompletableFuture.runAsync(() -> userDataDubboService.saveOrUpdateUserPersonalInfo(personalDubboInfoDTO));
                log.info("查询学历信息，同步更新个人信息表，成功：personalDubboInfoDTO={}"+ JSON.toJSONString(personalDubboInfoDTO));
            } catch (Exception e) {
                log.error("查询学历信息，同步更新个人信息表，失败：lastEducationSaveReqDTO={}, e={}" , JSON.toJSON(lastEducationSaveReqDTO), e.getMessage());
            }

            if(saveResult != null && saveResult>0){
                return true;
            }else {
                throw new BizException("USR19109");
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        } catch (ExecutionException e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }

    private String coverToDate(Long millions){
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(millions);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = sdf.format(c.getTime());
        return dateString;
    }

    @Override
    public void saveDataCallback(String userId, String jsonString) {
        try{
            queryAndSaveData(userId);
        }catch (Exception e){
            log.error("拉取解析保存学历信息出现异常", e);
        }
    }

    @Override
    public TianchengAuthService getTianchengAuthService() {
        return tianchengAuthEducationService;
    }


    @Override
    public String getH5ErrorMsgUrl() {
        return h5ErrorMsgUrl;
    }

    @Override
    public String getH5CallbackResultUrl() {
        return h5CallbackResultUrl;
    }

    @Override
    public String getDataCallbackUrl() {
        return dataCallbackUrl;
    }

    @Override
    public String getAuthBizName() {
        return "EducationAuth";
    }

    @Override
    public String getAuthChineseName() {
        return "学历";
    }

    @Override
    public UserDataTypeEnum getDataType() {
        return UserDataTypeEnum.EDUCATION_AUTHORIZE;
    }

    @Override
    public ThirdAuthResponseDTO getThirdAuthUrl(String userId, String createIp, String source) {
        return super.getThirdAuthUrl(userId, createIp, source);
    }

}
